#include "MyDockPreviewWindow.h"


///////////////////////////////////////////////////////////////////////////////
// MyDockPreviewWindow
//


static gint my_dock_preview_window_private_offset;        //用于定位instance中的private.
static gpointer my_dock_preview_window_parent_class = NULL;

static void my_dock_preview_window_class_init(MyDockPreviewWindowClass *klass);
static void my_dock_preview_window_init(MyDockPreviewWindow *window);
static gboolean my_dock_preview_window_draw(GtkWidget *widget, cairo_t *cr);



//implemention of functions

static inline gpointer my_dock_preview_window_get_instance_private(MyDockPreviewWindow *self)
{
  return G_STRUCT_MEMBER_P(self, my_dock_preview_window_private_offset);
}

GType my_dock_preview_window_get_type (void)		
{
  static GType my_dock_preview_window_type = 0;

  if (!my_dock_preview_window_type)       //lazy creation
    {
      const GTypeInfo type_info =
      {
        sizeof(MyDockPreviewWindowClass),
        NULL,                                                         //base_class_init()
        NULL,                                                      //base_class_finalize()
        (GClassInitFunc) my_dock_preview_window_class_init,                       //class_init()
        NULL,                                                        //class_finalize
        NULL,                                                       //class_data
        sizeof(MyDockPreviewWindow),                                          //instance size
        0,                                                           //n_preallocs
        (GInstanceInitFunc)my_dock_preview_window_init,                          //instance_init
        NULL,                                                       //value_table
      };

      my_dock_preview_window_type = g_type_register_static (GTK_TYPE_WINDOW, "MyDockPreviewWindow", &type_info, 0);

      //the offset of MyDockPreviewWindowPriv* in MyDockPreviewWindow
      my_dock_preview_window_private_offset = g_type_add_instance_private(my_dock_preview_window_type, sizeof(MyDockPreviewWindowPrivate));
    }

  return my_dock_preview_window_type;
}


static void my_dock_preview_window_class_init(MyDockPreviewWindowClass *klass)
{
    g_print("my_dock_preview_window_class_init.....\n");
    
    GtkWidgetClass *widget_class;

    widget_class = GTK_WIDGET_CLASS(klass);

    my_dock_preview_window_parent_class = g_type_class_peek_parent(klass);
    g_type_class_adjust_private_offset(klass, &my_dock_preview_window_private_offset);

    //
    //set methods
    //

    widget_class->draw = my_dock_preview_window_draw;


    //
    //set props
    //


    //
    //set signals
    //

  //
  //binding keys
  //

  //
  //install style property
  //

}

void my_dock_preview_window_init(MyDockPreviewWindow *window)
{
    g_print("my_dock_preview_window_init.....\n");

    GdkScreen *screen;
    GdkVisual *visual;
    
    screen = gdk_screen_get_default();
    visual = gdk_screen_get_rgba_visual(screen);

    if(gdk_screen_is_composited(screen) && visual)
    {
        gtk_widget_set_visual(GTK_WIDGET(window), visual);
        gtk_widget_set_app_paintable(GTK_WIDGET(window), TRUE);
    }
}



gboolean my_dock_preview_window_draw(GtkWidget *widget, cairo_t *cr)
{
    g_print("my_dock_preview_window_new.....\n");

    GtkStyleContext *context;
    GdkRGBA selected;

    context = gtk_widget_get_style_context(widget);
    gtk_style_context_lookup_color(context, "theme_selected_bg_color", &selected);

    if(gtk_widget_get_app_paintable(widget))        //支持透明
    {
        GtkAllocation alloc;
        gtk_widget_get_allocation(widget, &alloc);

        cairo_set_line_width(cr, 1.0);

        cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
        cairo_set_source_rgba(cr, 0, 0, 0, 0);
        cairo_paint(cr);

        cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
        selected.alpha = 0.25;
        gdk_cairo_set_source_rgba(cr, &selected);
        cairo_paint(cr);

        cairo_set_source_rgba(cr, 1.0, 1.0, 0, 1.0);
        cairo_rectangle(cr, alloc.x+0.5, alloc.y+ 0.5
                            , alloc.width - 1.0, alloc.height - 1.0);
        cairo_stroke(cr);
    }
    else
    {
        gdk_cairo_set_source_rgba(cr, &selected);
        cairo_paint(cr);
    }

    return G_SOURCE_REMOVE;
}


void my_dock_preview_window_update(MyDockPreviewWindow *widget,  const GdkRectangle *rect)
{
    g_print("my_dock_preview_window_update.....\n");

    if(rect->width <= 0 || rect->height <= 0)
    {
        gtk_widget_hide(GTK_WIDGET(widget));
        return;
    }

    gtk_window_move(GTK_WINDOW(widget), rect->x, rect->y);
    gtk_window_resize(GTK_WINDOW(widget), rect->width, rect->height);
    gtk_widget_show(GTK_WIDGET(widget));


    if(!gtk_widget_get_app_paintable(GTK_WIDGET(widget)))       //一般平台均支持app_paintable, 故不会执行该分支.
    {
        GdkWindow *gdkwin = gtk_widget_get_window(GTK_WIDGET(widget));

        if(rect->width > 2 && rect->height > 2)
        {
            cairo_region_t *region, *region2;
            cairo_rectangle_int_t region_rect = { 0, 0,
                rect->width - 2, rect->height - 2 };

            region = cairo_region_create_rectangle(&region_rect);
            region_rect.x++;
            region_rect.y++;
            region_rect.width -=2;
            region_rect.height -=2;
            region2 = cairo_region_create_rectangle(&region_rect);

            cairo_region_subtract(region, region2);
            gdk_window_shape_combine_region(gdkwin, region, 0, 0);

            cairo_region_destroy(region);
            cairo_region_destroy(region2);
        }
        else
        {
            g_print("simple combine 2\n");
            gdk_window_shape_combine_region(gdkwin, NULL, 0, 0);
        }

    }
}




GtkWidget* my_dock_preview_window_new(void)
{
    g_print("my_dock_preview_window_new.....\n");
    return GTK_WIDGET(g_object_new(TYPE_MY_DOCK_PREVIEW_WINDOW, "type", GTK_WINDOW_POPUP, NULL));
}
